
package com.projectxxxxxxxxxx.toggle;


import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.bluetooth.BluetoothAdapter;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.location.LocationManager;
import android.media.AudioManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

import com.projectxxxxxxxxxx.R;
import com.projectxxxxxxxxxx.RoboApplication;

public enum Toggle {

	GPS {
		@Override
		public boolean get() {
			return getGpsStatusLessApiLevel8();
		}

		//@SuppressLint({ "NewApi", "NewApi" })
		///@TargetApi(8)
		@Override
		public void toggle() {

			if (canToggleGPS()) {
				final Intent poke = new Intent();
				poke.setClassName("com.android.settings", "com.android.settings.widget.SettingsAppWidgetProvider");
				poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
				poke.setData(Uri.parse("3"));
				RoboApplication.getInstance().sendBroadcast(poke);

				if (getGpsStatusLessApiLevel8()) {
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_gps_off, Toast.LENGTH_SHORT).show();
				} else {
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_gps_on, Toast.LENGTH_SHORT).show();
				}
			} else {
				 if (getGpsStatusLessApiLevel8()) {
				 Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
				 intent.putExtra("enabled", false);
				 RoboApplication.getInstance().sendBroadcast(intent);
				 Toast.makeText(RoboApplication.getInstance(), R.string.toggle_gps_off, Toast.LENGTH_SHORT).show();
				
				 } else {
				 Intent intent = new Intent("android.location.GPS_ENABLED_CHANGE");
				 intent.putExtra("enabled", true);
				 RoboApplication.getInstance().sendBroadcast(intent);
				 Toast.makeText(RoboApplication.getInstance(), R.string.toggle_gps_on, Toast.LENGTH_SHORT).show();
				 }
				

			}
		}

		private boolean canToggleGPS() {
			PackageManager pacman = RoboApplication.getInstance().getPackageManager();
		    PackageInfo pacInfo = null;

		    try {
		        pacInfo = pacman.getPackageInfo("com.android.settings", PackageManager.GET_RECEIVERS);
		    } catch (NameNotFoundException e) {
		        return false; //package not found
		    }

		    if(pacInfo != null){
		        for(ActivityInfo actInfo : pacInfo.receivers){
		            //test if recevier is exported. if so, we can toggle GPS.
		            if(actInfo.name.equals("com.android.settings.widget.SettingsAppWidgetProvider") && actInfo.exported){
		                return true;
		            }
		        }
		    }

		    return false; //default
		}

		
		private boolean getGpsStatusLessApiLevel8() {
			ContentResolver cr = RoboApplication.getInstance().getContentResolver();
			String enabledProviders = Settings.Secure.getString(cr, Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
			if (!TextUtils.isEmpty(enabledProviders)) {
				String[] providersList = TextUtils.split(enabledProviders, ",");
				for (String provider : providersList) {
					if (LocationManager.GPS_PROVIDER.equals(provider)) {
						return true;
					}
				}
			}
			return false;
		}
	},
	WIFI {
		@Override
		public boolean get() {
			final ConnectivityManager connMgr = (ConnectivityManager) RoboApplication.getInstance().getSystemService(
					Context.CONNECTIVITY_SERVICE);
			final NetworkInfo wifi = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
			Log.e("rrrrrrrrrrrrrrrrrrrrr", wifi.isConnectedOrConnecting() + "");
			return wifi.isConnectedOrConnecting();
		}
		@Override
		public void toggle() {
			WifiManager wifiManager = (WifiManager) RoboApplication.getInstance()
					.getSystemService(Context.WIFI_SERVICE);
			if (wifiManager.isWifiEnabled()) {
				wifiManager.setWifiEnabled(false);
				Toast.makeText(RoboApplication.getInstance(), R.string.toggle_wifi_off, Toast.LENGTH_SHORT)
						.show();
			} else {
				wifiManager.setWifiEnabled(true);
				Toast.makeText(RoboApplication.getInstance(), R.string.toggle_wifi_on, Toast.LENGTH_SHORT)
						.show();
			}
		}
	},
	BLUETOOTH {
		// how to set a button
		// http://stackoverflow.com/questions/5735053/toggling-bluetooth-on-and-off
		@Override
		public boolean get() {
			BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
			if (bluetoothAdapter != null) {
				return bluetoothAdapter.isEnabled();
			}
			return false;
		}

		@Override
		public void toggle() {
			BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
			if (bluetoothAdapter != null) {
				if (bluetoothAdapter.isEnabled()) {
					bluetoothAdapter.disable();
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_bluetooth_off, Toast.LENGTH_SHORT)
							.show();
				} else {
					bluetoothAdapter.enable();
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_bluetooth_on, Toast.LENGTH_SHORT)
							.show();
				}
			}
		}
	},
	SILENT {
		@Override
		public boolean get() {
			AudioManager audioManager = (AudioManager) RoboApplication.getInstance().getSystemService(
					Context.AUDIO_SERVICE);
			return audioManager.getRingerMode() == AudioManager.RINGER_MODE_SILENT ? true : false;
		}

		@Override
		public void toggle() {
			AudioManager audioManager = (AudioManager) RoboApplication.getInstance().getSystemService(
					Context.AUDIO_SERVICE);
			if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_NORMAL) {
				audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
				Toast.makeText(RoboApplication.getInstance(), R.string.toggle_vibrate_on, Toast.LENGTH_SHORT).show();
			} else if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) {
				audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
				Toast.makeText(RoboApplication.getInstance(), R.string.toggle_silent_on, Toast.LENGTH_SHORT).show();
			} else {
				audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
				Toast.makeText(RoboApplication.getInstance(), R.string.toggle_silent_off, Toast.LENGTH_SHORT).show();
			}
		}
	},
	VIBRATE {

		@Override
		public boolean get() {
			AudioManager audioManager = (AudioManager) RoboApplication.getInstance().getSystemService(
					Context.AUDIO_SERVICE);
			return audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE ? true : false;

            // AudioManager audioManager = (AudioManager)
            // RoboApplication.getInstance().getSystemService(
            // Context.AUDIO_SERVICE);
            // return
            // audioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER)
            // ==
            // AudioManager.VIBRATE_SETTING_ON ? true
            // : false;
		}

		@Override
		public void toggle() {
			SILENT.toggle();
            AudioManager audioManager = (AudioManager) RoboApplication.getInstance().getSystemService(
                    Context.AUDIO_SERVICE);
            if (audioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER) == AudioManager.VIBRATE_SETTING_ON)
            {
                audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
                Toast.makeText(RoboApplication.getInstance(), R.string.toggle_vibrate_off, Toast.LENGTH_SHORT).show();
            } else {
                audioManager.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ON);
                Toast.makeText(RoboApplication.getInstance(), R.string.toggle_vibrate_on, Toast.LENGTH_SHORT).show();
            }
		}
	},
	AUTO_ROTATE {
		@Override
		public boolean get() {
			if (android.provider.Settings.System.getInt(RoboApplication.getInstance().getContentResolver(),
					Settings.System.ACCELEROMETER_ROTATION, 0) == 1) {
				return true;
			} else {
				return false;
			}
		}


		@Override
		public void toggle() {

			try {
				if (android.provider.Settings.System.getInt(RoboApplication.getInstance().getContentResolver(),
						Settings.System.ACCELEROMETER_ROTATION, 0) == 1) {
					android.provider.Settings.System.putInt(RoboApplication.getInstance().getContentResolver(),
							Settings.System.ACCELEROMETER_ROTATION, 0);
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_auto_rotate_off, Toast.LENGTH_SHORT)
							.show();
				} else {
					android.provider.Settings.System.putInt(RoboApplication.getInstance().getContentResolver(),
							Settings.System.ACCELEROMETER_ROTATION, 1);
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_auto_rotate_on, Toast.LENGTH_SHORT)
							.show();
				}
			} catch (Exception e) {
				e.printStackTrace();
				Toast.makeText(RoboApplication.getInstance(), "Try failed!", Toast.LENGTH_SHORT).show();
			}
		}
	},
	FLASH_LIGHT {
		// if it is not work then use this
		// http://stackoverflow.com/questions/7515309/widget-for-turning-on-off-camera-flashlight-in-android/8257771#8257771
		@Override
		public boolean get() {
//			if (RoboApplication.getInstance().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
//				Camera cam = Camera.open();
//				Parameters p = cam.getParameters();
//
//				if (p.getFlashMode() == Parameters.FLASH_MODE_TORCH) {
//					return true;
//				} else {
//					return false;
//				}
//			}
			return false;
		}

		Camera cam;
		Parameters p;
		@Override
		public void toggle() {
			if (RoboApplication.getInstance().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {

				if (cam == null) {
					cam = Camera.open();
				}
				if (p == null) {
					p = cam.getParameters();
				}
				if (p.getFlashMode().equals(Parameters.FLASH_MODE_TORCH)) {
					p.setFlashMode(Parameters.FLASH_MODE_OFF);
					cam.setParameters(p);
					cam.stopPreview();
					// cam.release();
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_flash_light_off, Toast.LENGTH_SHORT)
							.show();
				} else {
					p.setFlashMode(Parameters.FLASH_MODE_TORCH);
					cam.setParameters(p);
					cam.startPreview();
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_flash_light_on, Toast.LENGTH_SHORT)
							.show();
				}
			}
		}
	},
	DATA {
		// Data - disables Wifi, Bluetooth and 3G/4G data.
		@Override
		public boolean get() {
			if (WIFI.get() || BLUETOOTH.get() || MOBILE.get()) {
				return true;
			} else {
				return false;
			}
		}

		@Override
		public void toggle() {

			if (WIFI.get() || BLUETOOTH.get() || MOBILE.get()) {
				if (WIFI.get()) {
					WIFI.toggle();
				}
				if (BLUETOOTH.get()) {
					BLUETOOTH.toggle();
				}
				if (MOBILE.get()) {
					MOBILE.toggle();
				}
			} else {
				if (!WIFI.get()) {
					WIFI.toggle();
				}
				if (!BLUETOOTH.get()) {
					BLUETOOTH.toggle();
				}
				if (!MOBILE.get()) {
					MOBILE.toggle();
				}
			}
		}
	},
	MOBILE {
		@Override
		public boolean get() {
			final ConnectivityManager connMgr = (ConnectivityManager) RoboApplication.getInstance().getSystemService(
					Context.CONNECTIVITY_SERVICE);
			final NetworkInfo mobile = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
			Log.i(getClass().toString(), "   " + mobile.isConnected() + "       " + mobile.isAvailable());

            return mobile.isConnected();

            // if (mobile.isConnected()) {
            // return true;
            // } else {
            // return false;
            // }

			// boolean bRes = false;
			// final ConnectivityManager connMgr = (ConnectivityManager) RoboApplication.getInstance().getSystemService(
			// Context.CONNECTIVITY_SERVICE);
			// // Data Connection mode (only if correctly initialized)
			// if (connMgr != null) {
			// try {
			// // Get Connectivity Service state
			// NetworkInfo netInfo = connMgr.getNetworkInfo(0);
			//
			// // Data is enabled if state is CONNECTED
			// bRes = (netInfo.getState() == NetworkInfo.State.CONNECTED);
			// } catch (Exception e) {
			// bRes = false;
			// }
			// }
			//
			// return bRes;

		}

		boolean state = false;

		@Override
		public void toggle() {
			try {
				if (state /* get() */) {
					state = false;
					setMobileDataEnabled(RoboApplication.getInstance(), false);
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_mobile_off, Toast.LENGTH_SHORT)
							.show();
				} else {
					state = true;
					setMobileDataEnabled(RoboApplication.getInstance(), true);
					Toast.makeText(RoboApplication.getInstance(), R.string.toggle_mobile_on, Toast.LENGTH_SHORT).show();
				}
			} catch (Exception e) {
				try {
					Log.i(getClass().toString(), "           " + get());
					toggleTelephony();

				} catch (Exception ee) {
					ee.printStackTrace();
				}
				e.printStackTrace();
			}
		}


		public void toggleTelephony() throws ClassNotFoundException, SecurityException, NoSuchMethodException,
				IllegalArgumentException, IllegalAccessException, InvocationTargetException {
			
			Method dataConnSwitchmethod;
			Class telephonyManagerClass;
			Object ITelephonyStub;
			Class ITelephonyClass;
			TelephonyManager telephonyManager = (TelephonyManager) RoboApplication.getInstance().getSystemService(
					Context.TELEPHONY_SERVICE);

			telephonyManagerClass = Class.forName(telephonyManager.getClass().getName());			
			Method getITelephonyMethod = telephonyManagerClass.getDeclaredMethod("getITelephony");
			getITelephonyMethod.setAccessible(true);
			ITelephonyStub = getITelephonyMethod.invoke(telephonyManager);
			ITelephonyClass = Class.forName(ITelephonyStub.getClass().getName());
			
			if (telephonyManager.getDataState() == TelephonyManager.DATA_CONNECTED) {
				dataConnSwitchmethod = ITelephonyClass.getDeclaredMethod("disableDataConnectivity");
				Toast.makeText(RoboApplication.getInstance(), R.string.toggle_mobile_off, Toast.LENGTH_SHORT).show();
			} else {
				dataConnSwitchmethod = ITelephonyClass.getDeclaredMethod("enableDataConnectivity");
				Toast.makeText(RoboApplication.getInstance(), R.string.toggle_mobile_on, Toast.LENGTH_SHORT).show();
			}	
			
			dataConnSwitchmethod.setAccessible(true);
			dataConnSwitchmethod.invoke(ITelephonyStub);
		}

		private void setMobileDataEnabled(Context context, boolean enabled) throws ClassNotFoundException,
				SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException,
				NoSuchMethodException, InvocationTargetException {
			final ConnectivityManager conman = (ConnectivityManager) context
					.getSystemService(Context.CONNECTIVITY_SERVICE);
			final Class conmanClass = Class.forName(conman.getClass().getName());
			final Field iConnectivityManagerField = conmanClass.getDeclaredField("mService");
			iConnectivityManagerField.setAccessible(true);
			final Object iConnectivityManager = iConnectivityManagerField.get(conman);
			final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
			final Method setMobileDataEnabledMethod = iConnectivityManagerClass.getDeclaredMethod(
					"setMobileDataEnabled", Boolean.TYPE);
			setMobileDataEnabledMethod.setAccessible(true);
			setMobileDataEnabledMethod.invoke(iConnectivityManager, enabled);
		}
	},
	// need access
	BLUETOOTH_HIDDEN {
		@Override
		public boolean get() {
			return false;
		}

		@Override
		public void toggle() {
		}
	},
	LOCK {
		@Override
		public boolean get() {
			return false;
		}

		@Override
		public void toggle() {
			// String service = Activity.KEYGUARD_SERVICE;
			// KeyguardManager mgr = (KeyguardManager) RoboApplication.getInstance().getSystemService(service);
			// KeyguardLock lock = mgr.newKeyguardLock(Activity.KEYGUARD_SERVICE);
			// lock.reenableKeyguard();
			// DevicePolicyManager devicePolicyManager = new DevicePolicyManager
			// devicePolicyManager.lockNow();

			// DevicePolicyManager deviceManager = (DevicePolicyManager) RoboApplication.getInstance().getSystemService(
			// Context.DEVICE_POLICY_SERVICE);
			// deviceManager.lockNow();

			// ComponentName devAdminReceiver; // this would have been declared in your class body
			// // then in your onCreate
			// DevicePolicyManager mDPM = (DevicePolicyManager)
			// RoboApplication.getInstance().getSystemService(Context.DEVICE_POLICY_SERVICE);
			// devAdminReceiver = new ComponentName(RoboApplication.getInstance(), deviceAdminReceiver.class);
			// // then in your onResume
			//
			// boolean admin = mDPM.isAdminActive(devAdminReceiver);
			// if (admin)
			// mDPM.lockNow();
			// else
			// Log.i(tag, "Not an admin");
		}
	};

	public abstract boolean get();
	public abstract void toggle();



}